package api

import (
	"moss/meta"
	"moss/proto"
	"moss/status"
	"net/url"
	"strings"
)

func PutBucketWebsite(requestId string, accessKeyId string, bucketName string, xmlDoc proto.WebsiteConfiguration) status.Status {
	indexSuffix := xmlDoc.IndexDocument.Suffix
	errorKey := xmlDoc.ErrorDocument.Key
	if !validIdentifier(bucketName) {
		return status.InvalidBucketName
	}
	bucketMeta, ok := meta.GetBucketInfo(bucketName)
	if !ok {
		return status.NoSuchBucket
	}

	if bucketMeta.OwnerAccessKeyId != accessKeyId {
		return status.AccessDenied
	}

	if len(indexSuffix) == 0 || strings.ContainsAny(indexSuffix, "/") {
		return status.InvalidArgument
	}
	meta.PutWebsite(bucketName, accessKeyId, indexSuffix, errorKey)
	return status.Success
}

func GetBucketWebsite(requestId string, accessKeyId string, bucketName string) (*proto.WebsiteConfiguration, status.Status) {
	if !validIdentifier(bucketName) {
		return nil, status.InvalidBucketName
	}
	bucketMeta, ok := meta.GetBucketInfo(bucketName)
	if !ok {
		return nil, status.NoSuchBucket
	}

	if bucketMeta.OwnerAccessKeyId != accessKeyId {
		return nil, status.AccessDenied
	}

	var xmlDoc proto.WebsiteConfiguration
	conf, ok := meta.GetWebsite(bucketName)
	if !ok {
		return nil, status.NoSuchWebsiteConfiguration
	}

	xmlDoc.IndexDocument.Suffix = conf.Suffix
	xmlDoc.ErrorDocument.Key = conf.Key
	return &xmlDoc, status.Success
}

func DeleteBucketWebsite(requestId string, accessKeyId string, bucketName string) status.Status {
	if !validIdentifier(bucketName) {
		return status.InvalidBucketName
	}

	bucketMeta, ok := meta.GetBucketInfo(bucketName)
	if !ok {
		return status.NoSuchBucket
	}

	if bucketMeta.OwnerAccessKeyId != accessKeyId {
		return status.AccessDenied
	}

	_, ok = meta.GetWebsite(bucketName)
	if !ok {
		return status.NoSuchBucket
	}

	meta.DeleteWebsite(bucketName)
	return status.Success
}

// Other GET anonymous request can redirect here
func GetWebsiteContent(bucketName string, url *url.URL) (*meta.Object, status.Status) {
	if !validIdentifier(bucketName) {
		return nil, status.InvalidBucketName
	}

	website, ok := meta.GetWebsite(bucketName)
	if !ok {
		return nil, status.NoSuchWebsiteConfiguration
	}

	objectName := url.Path
	if strings.HasSuffix(objectName, "/") {
		objectName = objectName + website.Suffix
	}

	objectName = strings.TrimPrefix(objectName, "/")
	objectMeta, exist := meta.GetObjectInfo(bucketName, objectName)

	if !exist {
		objectName = objectName + "/" + website.Suffix
		objectName = strings.TrimPrefix(objectName, "/")
		objectMeta, exist = meta.GetObjectInfo(bucketName, objectName)
	}

	if !exist {
		objectMeta, _ = meta.GetObjectInfo(bucketName, website.Key)
		return objectMeta, status.NoSuchKey
	}

	return objectMeta, status.Success
}
